//-------------------------------------------------------------------
//	Copyright (c) 2013  Zhirnov Andrey
//	This file is part of the "Noise Library" project.
//	See copyright notice in "linNoiseCL.h".
//-------------------------------------------------------------------

#pragma once

#include "../CSource.h"

namespace Noise
{
	
	//
	// Function Source with constant
	//

	class CSourceConst : public CSource
	{
	// types
	protected:
		typedef CSourceConst	Self;


	// variables
	protected:
		real		_value;
		
		static const
			ESource	_sourceType = CONSTANT;

	// methods
	public:
		CSourceConst () : _value(0)
		{}

		~CSourceConst ()
		{}

		ESourceState GetState () const
		{
			return SOURCE_COMPLETE;
		}
		
		virtual void Delete ()
		{
			_value = 0;
		}

		virtual EResult GetInteger (ESourceQuery type, int *v, int count) const
		{
			CHECK_ARGUMENT_R( count >= 1, INVALID_VALUE );

			switch ( type )
			{
				case SOURCE_STATE :
					v[0] = GetState();
					return OK;

				case SOURCE_TYPE :
					v[0] = _sourceType;
					return OK;

				case SOURCES_COUNT :
					v[0] = 1;
					return OK;

				case INPUT_SOURCES :
					v[0] = 0;
					return OK;
			}
			return INVALID_ENUM;
		}
		
		virtual EResult SetArg (EArgument type, const real *v, int count)
		{
			CHECK_ARGUMENT_R( count >= 1, INVALID_VALUE );

			switch ( type )
			{
				case ARG_CONST :	_value = v[0];	return OK;
			}
			return INVALID_ENUM;
		}
		
		virtual EResult GetArg (EArgument type, real *v, int count) const
		{
			CHECK_ARGUMENT_R( count >= 1, INVALID_VALUE );

			switch ( type )
			{
				case ARG_CONST :	v[0] = _value;	return OK;
			}
			return INVALID_ENUM;
		}
		
		virtual CSourcePtr Clone () const override
		{
			Self *	src = new Self();
			src->_value = _value;
			return src;
		}
		
		virtual void PreBuild (const TPreBuildData &data) override
		{
		}

		virtual bool BuildFunction (TFunctionData &data) override
		{
			CSource::BuildFunctionHeader( data.source, _id );
			data.source << " (real)(" << _value << ")\n";
			return true;
		}
		
		NATIVE(
		template <typename Real>
		Real NativeFunction (const TVec<Real,3> &vPoint)
		{
			return Real(_value);
		}
		
		virtual float32 NativeFunction32 (const fvec3 &vPoint) override
		{
			return NativeFunction<float32>( vPoint );
		}

		virtual float64 NativeFunction64 (const dvec3 &vPoint) override
		{
			return NativeFunction<float64>( vPoint );
		})

		static bool CreateSource (CSourcePtr &src, CContext *context, ESource type)
		{
			ASSERT( type == _sourceType );

			src = new Self();
			return true;
		}
	};

}	// Noise